package com.fjsh.config;

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import java.util.Map;

/**
 * 注意：使用ES端的微服务需要在配置中心添加ES配置
 */
@Configuration
public class ElasticSearchConfig {

    @Value("${spring.data.elasticsearch.cluster-nodes}")
    private String[] esNodes;
    @Value("${spring.data.elasticsearch.properties}")
    private Map<String,String> properties;

    private final static String HTTP = "http";
    private final static int PORT = 9200;

    @Bean(destroyMethod = "close")
    public RestHighLevelClient restHighLevelClient() {

        String userName = properties.get("username");
        String password = properties.get("password");
        Integer connectTimeOut = Integer.valueOf(properties.get("connecttimeout"));
        Integer maxConnTotal = Integer.valueOf(properties.get("maxconntotal"));

        HttpHost[] httpHosts = new HttpHost[esNodes.length];
        // 将地址转换为http主机数组，未配置端口则采用默认9200端口，配置了端口则用配置的端口
        for (int i = 0; i < httpHosts.length; i++) {
            if (!StringUtils.isEmpty(esNodes[i])) {
                if (esNodes[i].contains(":")) {
                    String[] uris = esNodes[i].split(":");
                    httpHosts[i] = new HttpHost(uris[0], Integer.parseInt(uris[1]), HTTP);
                } else {
                    httpHosts[i] = new HttpHost(esNodes[i], PORT, HTTP);
                }
            }
        }
        // 判断，如果未配置用户名，则进行无用户名密码连接，配置了用户名，则进行用户名密码连接
        if (StringUtils.isEmpty(userName)) {
            return new RestHighLevelClient(RestClient.builder(httpHosts));
        } else {
            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
            RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(httpHosts)
                .setHttpClientConfigCallback((httpClientBuilder) -> {
                    httpClientBuilder.setMaxConnTotal(maxConnTotal);
                    httpClientBuilder.disableAuthCaching();
                    httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                    return httpClientBuilder;
                })
                .setRequestConfigCallback(builder -> {
                    builder.setConnectTimeout(connectTimeOut);
                    return builder;
                })
            );
            return client;
        }
    }

}
